package cn.net.isir.core;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

@Repository
public abstract class BasicDao<E> {
    private Class<E> eClass;

    @Resource
    protected SqlSessionTemplate sqlSessionTemplate;

    final static String DEFAULT_SQL_ID = "selectList";
    final static String DEFAULT_ONE_SQL_ID = "selectOne";
    final static String DEFAULT_COUNT_SQL_ID = "selectCount";

    public BasicDao() {
        // 一定要放在构造函数里
        eClass = (Class<E>) getModelClass(0);// 0表示第一个泛型
    }

    /**
     * {@code return E.class.getName()}
     */
    protected String getNamespace() {
        return eClass.getName();
    }

    /**
     * 获取运行对象中实际的泛型类型
     *
     * @param index 第index个泛型
     * @return 类型
     */
    private Class<?> getModelClass(int index) {
        Type genType = this.getClass().getGenericSuperclass();// 得到泛型父类
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();//一个泛型类可能有多个泛型形参，比如ClassName<T,K> 这里有两个泛型形参T和K，Class Name<T> 这里只有1个泛型形参T
        if (params.length - 1 < index) {
            return null;
        }
        return (Class) params[index];
    }

    public E selectByPrimaryKey(String id) {
        BasicModel basicModel = new BasicModel();
        basicModel.setId(id);
        return this.sqlSessionTemplate.selectOne(getNamespace() + ".selectByPrimaryKey", basicModel);
    }

    public E selectOne(Object parameter) {
        return this.sqlSessionTemplate.selectOne(getNamespace() + ".selectOne", parameter);
    }

    public E selectOne(Object parameter, String statement) {
        return this.sqlSessionTemplate.selectOne(getNamespace() + "." + statement, parameter);
    }

    /**
     * 不分页的查询列表：使用[固定的selectList方法]，根据[泛型参数]查询[泛型列表]
     *
     * @param parameter 泛型参数
     * @return 列表
     */
    public List<E> selectList(Object parameter) {
        return this.sqlSessionTemplate.selectList(getNamespace() + ".selectList", parameter);
    }

    /**
     * 不分页的查询列表：使用[自定义的statement方法]，根据[泛型参数]查询[泛型列表]
     *
     * @param parameter 泛型参数
     * @param statement 方法名
     * @return 列表
     */
    public List<E> selectList(Object parameter, String statement) {
        return this.sqlSessionTemplate.selectList(getNamespace() + "." + statement, parameter);
    }

    /**
     * 带分页的查询列表：使用[固定的selectList方法]，根据[泛型参数]查询[泛型列表]
     *
     * @param parameter 泛型参数
     * @param pageNum   页码
     * @param pageSize  分页大小
     * @return 分页类
     */
    public PageInfo<E> selectPageList(Object parameter, Integer pageNum, Integer pageSize) {
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = 0;
        }
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(sqlSessionTemplate.selectList(getNamespace() + ".selectList", parameter));
    }

    /**
     * 带分页的查询列表：使用[自定义的statement方法]，根据[Map参数]查询[Model列表]
     *
     * @param parameter Map或实体类参数
     * @param statement 语句
     * @param pageNum   页码
     * @param pageSize  分页大小
     * @return 分页类
     */
    public PageInfo selectPageList(Object parameter, String statement, Integer pageNum, Integer pageSize) {
        if (pageNum == null || pageSize == null) {
            pageNum = 1;
            pageSize = 0;
        }
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(sqlSessionTemplate.selectList(getNamespace() + "." + statement, parameter));
    }

    public int selectCount(Object parameter) {
        return this.sqlSessionTemplate.selectOne(getNamespace() + ".selectCount", parameter);
    }

    public int update(Object parameter) {
        return this.sqlSessionTemplate.update(getNamespace() + ".update", parameter);
    }

    public int update(Object parameter, String statement) {
        return this.sqlSessionTemplate.update(getNamespace() + "." + statement, parameter);
    }

    public int insert(Object parameter) {
        return this.sqlSessionTemplate.insert(getNamespace() + ".insert", parameter);
    }

    public int insert(Object parameter, String statement) {
        return this.sqlSessionTemplate.insert(getNamespace() + "." + statement, parameter);
    }

    /**
     * 软删除-将isValid设置为0
     *
     * @param id 要删除的id
     * @return 修改记录数量
     */
    public int delete(String id) {
        BasicModel basicModel = new BasicModel();
        basicModel.setId(id);
        return this.sqlSessionTemplate.update(getNamespace() + ".delete", basicModel);
    }

    /**
     * 软反删除-将isValid设置为1
     *
     * @param id 要反删除的id
     * @return 修改记录数量
     */
    public int unDelete(String id) {
        BasicModel basicModel = new BasicModel();
        basicModel.setId(id);
        return this.sqlSessionTemplate.update(getNamespace() + ".unDelete", basicModel);
    }

//    public int delete(String id) {
//        return this.sqlSessionTemplate.delete(getNamespace() + ".delete", id);
//    }
//
//    public int delete(String id, String statement) {
//        return this.sqlSessionTemplate.delete(getNamespace() + "." + statement, id);
//    }
//
//    public int delete(Object parameter, String statement) {
//        return this.sqlSessionTemplate.delete(getNamespace() + "." + statement, parameter);
//    }
}
